#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <cassert>

static void handler(int signum)
{
    std::cout << "捕获信号：" << signum << std::endl;
    // exit(1); 不终止进程
}

static void showPending(sigset_t &pending)
{
    for (int sig = 31; sig >= 1; sig--)
    {
        if (sigismember(&pending, sig))
            std::cout << "1";
        else
            std::cout << "0";
    }
    std::cout << std::endl;
}

int main()
{
    // 0. 测试 捕捉2号信号 不让其执行默认终止动作
    signal(2, handler);
    // 1. 定义信号集对象
    sigset_t set, oldset;
    sigset_t pending;
    // 2. 初始化
    sigemptyset(&set);
    sigemptyset(&oldset);
    sigemptyset(&pending);
    // 3. 添加要进行屏蔽的信号
    sigaddset(&set, 2 /*SIGINT*/);
    // 4. 设置set到内核中对应的进程内部[默认情况进程不会对任何信号进行block]
    int n = sigprocmask(SIG_BLOCK, &set, &oldset);
    assert(n == 0);
    (void)n;

    std::cout << "block 2 号信号成功...., pid: " << getpid() << std::endl;
    // 5. 重复打印当前进程的pending信号集
    int count = 0;
    while (true)
    {
        // 5.1 获取当前进程的pending信号集
        sigpending(&pending);
        // 5.2 显示pending信号集中的没有被递达的信号
        showPending(pending);
        sleep(1);
        count++;
        if (count == 20)
        {
            // 默认情况下 解除2号信号的阻塞 确实会进行递达
            // 2号信号的默认处理动作是终止进程 需要对2号信号进行捕捉
            std::cout << "Unblock signal 2" << std::endl;
            int n = sigprocmask(SIG_SETMASK, &oldset, nullptr);
            assert(n == 0);
            (void)n;
        }
    }

    return 0;
}
